package com.mrd.frame.onlinepay.refund.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.mrd.frame.domain.AccessConfig;
import com.mrd.frame.domain.Order;
import com.mrd.frame.domain.OrderInteraction;
import com.mrd.frame.domain.PayConfig;
import com.mrd.frame.domain.TradeStatement;
import com.mrd.frame.domain.message.RefundMessage;
import com.mrd.frame.domain.params.RefundParams;
import com.mrd.frame.onlinepay.refund.IRefund;
import com.mrd.frame.service.OrderInteractionService;
import com.mrd.frame.service.OrderService;
import com.mrd.frame.service.TradeStatementService;
import com.mrd.weixinpay.util.Constents;
import com.mrd.weixinpay.util.PayCertificateSSL;
import com.mrd.weixinpay.util.PayCommonUtil;
import com.mrd.weixinpay.util.XMLUtil;

@Component("wxRefund")
public class WxRefund implements IRefund {
	private static final Logger	logger	= Logger.getLogger(WxRefund.class);

	@Value("${pay.weixin.requestRefund}")
	private String	            requestRefund;

	public Map<String, Object> refund(HttpServletResponse response,OrderInteraction orderInt,
	        OrderInteractionService orderInteractionService,AccessConfig accessConfig,Order order,
	        TradeStatement payStatement, RefundParams refParams,OrderService orderService,
	        TradeStatementService tradeStatementService) {
		Map<String, Object> reMap = new HashMap<String, Object>();
		String resultMsg = "";
		RefundMessage refundMsg = new RefundMessage();
		// 微信退款
		// 将客户端向服务端发起的退款请求存入交互表中
		orderInt.setOrderId(order.getOrderId());
		orderInt.setType("B1");
		orderInt.setStatus("0");
		int b1 = orderInteractionService.insert(orderInt);

		// 向微信发起支付请求的参数
		String appid = accessConfig.getAppId();  // appid
		String mch_id = accessConfig.getMchId(); // 商业号
		String key = accessConfig.getPrivateKey();
		// 随机数
		String currTime = PayCommonUtil.getCurrTime();
		String strTime = currTime.substring(8, currTime.length());
		String strRandom = PayCommonUtil.buildRandom(4) + "";
		String nonce_str = strTime + strRandom;
		// 获取发起支付请求的电脑 ip
		String spbill_create_ip = PayConfig.createIpLochost;
		String out_refund_no = order.getOrderId();// 退款单号
		String out_trade_no = payStatement.getOrderId();// 支付单号
		String refund_fee = String.valueOf(refParams.getRefundAmount());// 退款金额
		String total_fee = String.valueOf(refParams.getTotalAmount());
		String op_user_id = accessConfig.getMchId();// 操作员帐号, 默认为商户号

		SortedMap<Object, Object> reqParams = new TreeMap<Object, Object>();
		reqParams.put("appid", appid);
		reqParams.put("mch_id", mch_id);
		reqParams.put("nonce_str", nonce_str);
		reqParams.put("out_trade_no", out_trade_no);
		reqParams.put("out_refund_no", out_refund_no);
		reqParams.put("total_fee", total_fee);
		reqParams.put("op_user_id", op_user_id);
		reqParams.put("refund_fee", refund_fee);
		String sign = PayCommonUtil.createSign("UTF-8", reqParams, key);
		reqParams.put("sign", sign);
		String requestXML = PayCommonUtil.getRequestXml(reqParams);
		logger.info("系统发送的退款请求信息：" + requestXML);
		System.out.println("系统发送的退款请求信息：  " + requestXML);
		// String resXml = HttpUtil.postData(PayConfig.requestRefund, requestXML);
		String path = accessConfig.getCertificatePath();// 证书的存储路径(每个业务系统对应的都不一样)PayConfig.certificatePath
		String resXml = "";
		try {
			// PayConfig.requestRefund
			resXml = PayCertificateSSL.doRefund(requestRefund, requestXML, path, mch_id);
			logger.info("微信返回的退款信息：" + resXml);
			System.out.println("微信返回的退款信息：" + resXml);
			Map resMap = XMLUtil.doXMLParse(resXml);
			// 服务端向第三方发起退款请求信息存到交互表中
			orderInt.setCreateTime(new Date());
			orderInt.setParameters(requestXML);
			orderInt.setOrderInteractionId(String.valueOf(System.currentTimeMillis()));
			orderInt.setType("B2");
			orderInt.setStatus("0");
			Integer B2 = orderInteractionService.insert(orderInt);

			// 将第三方返回给服务端的退款信息存入交互表
			orderInt.setCreateTime(new Date());
			orderInt.setParameters(resXml);
			orderInt.setOrderInteractionId(String.valueOf(System.currentTimeMillis()));
			orderInt.setType("B3");
			orderInt.setStatus("0");
			Integer B3 = orderInteractionService.insert(orderInt);

			// 退款成功：更新退款订单表，更新资金流水表，返回退款结果给客户端，将此信息存入交互记录表
			String result_code = (String) resMap.get("result_code");
			String refund_id = (String) resMap.get("refund_id");
			int retrefund_fee =Integer.parseInt((String) resMap.get("refund_fee")) ;
			String return_code = (String) resMap.get("return_code");
			String return_msg = (String) resMap.get("return_msg");
			String err_code_des = (String) resMap.get("err_code_des");
			if("SUCCESS".equals(result_code)) {
				// 更新订单表
				order.setStatus("2");
				order.setThirdOrderId(refund_id);
				orderService.updateByPrimaryKeySelective(order);

				// 存入资金流水表
				TradeStatement tradeStatement = new TradeStatement();
				tradeStatement.setOrderId(order.getOrderId());
				List<TradeStatement> trade = new ArrayList<>();
				trade = tradeStatementService.selectSelective(tradeStatement);
				if(!(trade.size() > 0)) {
					tradeStatement.setOrderId(order.getOrderId());
					tradeStatement.setPayChannel("1");
					tradeStatement.setThirdOrderId(refund_id);
					tradeStatement.setTotalAmount(retrefund_fee);
					tradeStatement.setTradeNo(refParams.getOutRefundNo());
					tradeStatement.setTradeTime(new Date());
					tradeStatement.setRelatedTradeNo(refParams.getOutTradeNo());
					tradeStatement.setTradeType("2");
					tradeStatement
					        .setTradingStatementsId(String.valueOf(System.currentTimeMillis()));
					tradeStatement.setUserKey(order.getUserKey());
					tradeStatementService.insert(tradeStatement);

				}
				// 封装返回给客户端的信息
				// RefundMessage refundMsg = new RefundMessage();
				refundMsg.setOutRefundNo(refParams.getOutRefundNo());// 商户退款单号
				refundMsg.setOutTradeNo(refParams.getOutTradeNo());// 商户订单号
				refundMsg.setCashFee((String) resMap.get("cash_fee"));// 现金支付金额
				refundMsg.setCode(Integer.parseInt("1"));// 请求成功
				refundMsg.setFundChange("Y");// 资金发生变化
				refundMsg.setGmtRefundPay(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss")
				        .format(new Date()));// 退款时间
				refundMsg.setMessage(Constents.SUCCESMESSAGE);// 请求信息反馈
				refundMsg.setOrderId(out_trade_no);// 平台支付单号
				refundMsg.setRefundAmount(retrefund_fee);// 退款的金额
				refundMsg.setRefundId(order.getOrderId());// 平台退款单号
				refundMsg.setResultCode("SUCCESS");// 返回代码
				refundMsg.setReturnCode("0");// 返回代码
				refundMsg.setReturnMsg(return_msg);// 返回信息
				refundMsg.setSign(refParams.getSign());// 签名
				refundMsg.setTotalAmount(Integer.parseInt(total_fee));// 订单总金额
				refundMsg.setThreeRefundId(refund_id);// 第三方返回的退款单号

				// 将退款反馈至客户端的信息存入交互表
				orderInt.setCreateTime(new Date());
				orderInt.setParameters(resXml);
				orderInt.setOrderInteractionId(String.valueOf(System.currentTimeMillis()));
				orderInt.setType("B4");
				orderInt.setStatus("0");

				// 响应客户端的退款请求
				// printRefunResultToSystem(response, refundMsg, orderInt);
			} else {
				// 退款失败：更新退款订单表，返回退款结果给客户端,将此信息存入交互记录表

				// 更新退款订单为失败
				order.setStatus("0");
				orderService.updateByPrimaryKeySelective(order);

				// 封装返回给客户端的信息
				// RefundMessage refundMsg = new RefundMessage();
				refundMsg.setOutRefundNo(refParams.getOutRefundNo());// 商户退款单号
				refundMsg.setOutTradeNo(refParams.getOutTradeNo());// 商户订单号
				refundMsg.setCashFee((String) resMap.get("cash_fee"));// 现金支付金额
				refundMsg.setCode(Integer.parseInt("0"));// 请求失败
				refundMsg.setFundChange("N");// 资金未发生变化
				// refundMsg.setGmtRefundPay(new
				// SimpleDateFormat("yyyy-MM-dd hh:mm:ss")
				// .format(new Date()));// 退款时间
				refundMsg.setMessage(Constents.FAULTMESSAGE);// 请求信息反馈
				refundMsg.setOrderId(out_trade_no);// 平台支付单号
				refundMsg.setRefundAmount(refParams.getRefundAmount());// 请求的退款的金额
				refundMsg.setRefundId(order.getOrderId());// 平台退款单号
				refundMsg.setResultCode("FAIL");// 返回代码
				refundMsg.setReturnCode("-1");// 返回代码
				refundMsg.setReturnMsg("退款失败，原因如下：" + err_code_des);// 第三方返回错误提示信息
				refundMsg.setSign(refParams.getSign());// 签名
				refundMsg.setTotalAmount(Integer.valueOf(total_fee));// 订单总金额
				// refundMsg.setThreeRefundId(refund_id);// 第三方返回的退款单号

				// 响应客户端的退款请求
				// printRefunResultToSystem(response, refundMsg, orderInt);
			}

		} catch (Exception e) {
			e.printStackTrace();

		} finally {
			// 此时请求第三方退款出错，直接返回错误信息改业务系统，并记录到交互表中

			// 服务端向第三方发起退款请求信息存到交互表中
			orderInt.setCreateTime(new Date());
			orderInt.setParameters(requestXML);
			orderInt.setOrderInteractionId(String.valueOf(System.currentTimeMillis()));
			orderInt.setType("B2");
			orderInt.setStatus("1");
			Integer B2 = orderInteractionService.insert(orderInt);

			// 封装返回给客户端的信息
			// RefundMessage refundMsg = new RefundMessage();
			refundMsg.setOutRefundNo(refParams.getOutRefundNo());// 商户退款单号
			refundMsg.setOutTradeNo(refParams.getOutTradeNo());// 商户订单号
			refundMsg.setCode(Integer.parseInt("0"));// 请求失败
			refundMsg.setFundChange("N");// 资金未发生变化
			refundMsg.setMessage(Constents.FAULTMESSAGE);// 请求信息反馈
			refundMsg.setOrderId(out_trade_no);// 平台支付单号
			refundMsg.setResultCode("FAIL");// 返回代码
			refundMsg.setReturnCode("FAIL");// 返回代码
			refundMsg.setReturnMsg("退款失败,请稍后重新发起退款请求");// 第三方返回错误提示信息
			refundMsg.setSign(refParams.getSign());// 签名
			refundMsg.setTotalAmount(Integer.valueOf(total_fee));// 订单总金额

			// try {
			// // printRefunResultToSystem(response, refundMsg, orderInt);
			// } catch (IOException e) {
			// e.printStackTrace();
			// }

		}
		reMap.put("resultMsg", refundMsg);
		return reMap;

	}

}
